<template>
    <div v-if="searchDialogVisible" class="search-text-container" :style="searchBoxPosition">
        <!--拖拽部分-->
        <div class="search-drag" @mousedown="startDragging">
            <i class="iconfont icon-drag-vertical"></i>
        </div>
        <div class="search-left">
            <el-icon class="open-btn" :class="{'open': isShowReplace}" @click.stop="isShowReplace=!isShowReplace">
                <ArrowRightBold/>
            </el-icon>
        </div>
        <div class="search-right">
            <div class="search-wrap">
                <el-input size="small" style="width: 130px" placeholder="查询" v-model="searchText"
                          @input="handleSearch"/>
                <el-tooltip effect="dark" placement="bottom" content="区分大小写">
                    <i class="iconfont icon-hulvedaxiaoxie" :class="{'active': caseSensitive}"
                       @click.stop="handleCaseSensitive"></i>
                </el-tooltip>
                <el-tooltip effect="dark" placement="bottom" content="上一个">
                    <i class="iconfont icon-pre" @click.stop="handleFindPrev"></i>
                </el-tooltip>
                <el-tooltip effect="dark" placement="bottom" content="下一个">
                    <i class="iconfont icon-next" @click.stop="handleFindNext"></i>
                </el-tooltip>
                <i class="iconfont icon-close" @click="handleClose"></i>
            </div>
            <span class="search-divider" v-show="isShowReplace"></span>
            <div class="replace-wrap" v-show="isShowReplace">
                <el-input size="small" style="width: 130px" placeholder="替换" v-model="replaceText"/>
                <el-tooltip effect="dark" placement="bottom" content="替换">
                    <i class="iconfont icon-replace" @click.stop="handleReplace"></i>
                </el-tooltip>
                <el-tooltip effect="dark" placement="bottom" content="全部替换">
                    <i class="iconfont icon-replace-all" @click.stop="handleReplaceAll"></i>
                </el-tooltip>
            </div>
        </div>
    </div>
</template>

<script setup>
import {ArrowRightBold} from "@element-plus/icons-vue";
import {ref, defineProps, defineEmits, computed, reactive} from "vue";

const props = defineProps({
    open: Boolean,
})

const emit = defineEmits(["update:open", 'searchEvent']);

// 初始位置
const searchBoxPosition = reactive({
    top: '60px',
    right: '20px'
});

// 拖拽相关状态
// 定义一个响应式的布尔变量，用于追踪是否正在拖动
const isDragging = ref(false);
// 定义一个响应式的对象，用于存储拖动偏移量
const dragOffset = reactive({
    x: 0,
    y: 0
});

const isShowReplace = ref(false);
// 查询文本
const searchText = ref("");
// 替换文本
const replaceText = ref("");
// 忽略大小写
const caseSensitive = ref(false);

const searchDialogVisible = computed({
    get() {
        return props.open;
    },
    set(val) {
        emit("update:open", val);
    }
})

/** 查询 */
function handleSearch() {
    emit('searchEvent', 'findNext', {
        searchText: searchText.value,
        replaceText: replaceText.value,
        caseSensitive: caseSensitive.value,
    })
}

/** 切换大小写 */
function handleCaseSensitive() {
    caseSensitive.value = !caseSensitive.value;
    handleSearch();
}

/** 下一个方法 */
function handleFindNext() {
    handleSearch();
}

/** 上一个方法 */
function handleFindPrev() {
    emit('searchEvent', 'findPrev', {
        searchText: searchText.value,
        replaceText: replaceText.value,
        caseSensitive: caseSensitive.value,
    })
}

/** 替换方法 */
function handleReplace() {
    emit('searchEvent', 'replace', {
        searchText: searchText.value,
        replaceText: replaceText.value,
        caseSensitive: caseSensitive.value,
    })
}

/** 替换全部方法 */
function handleReplaceAll() {
    emit('searchEvent', 'replaceAll', {
        searchText: searchText.value,
        replaceText: replaceText.value,
        caseSensitive: caseSensitive.value,
    })
}

/** 关闭搜索弹窗 */
function handleClose() {
    searchDialogVisible.value = false;
}

/**
 * 开始拖动的函数
 * @param {MouseEvent} event - 触发的鼠标事件
 */
function startDragging(event) {
    isDragging.value = true;

    // 获取目标元素的位置信息
    const rect = event.target.getBoundingClientRect();
    // 计算鼠标点击位置相对于元素左上角的偏移量
    dragOffset.x = event.clientX - rect.left;
    dragOffset.y = event.clientY - rect.top;

    // 添加鼠标移动和释放事件监听器
    document.addEventListener('mousemove', onMouseMove);
    document.addEventListener('mouseup', onMouseUp);
}

/**
 * 鼠标移动时的处理函数
 * @param {MouseEvent} event - 触发的鼠标事件
 */
function onMouseMove(event) {
    if (!isDragging.value) return;

    // 计算新的鼠标位置，并减去初始偏移量
    const x = event.clientX - dragOffset.x;
    const y = event.clientY - dragOffset.y;

    // 设置新的位置
    searchBoxPosition.top = `${y}px`;
    searchBoxPosition.right = `${window.innerWidth - (x + rect().width)}px`;

    // 禁止文本选择，防止用户在拖动时选择页面内容
    document.body.style.userSelect = 'none';
}

/**
 * 鼠标释放时的处理函数
 */
function onMouseUp() {
    isDragging.value = false;
    // 移除鼠标移动和释放事件监听器
    document.removeEventListener('mousemove', onMouseMove);
    document.removeEventListener('mouseup', onMouseUp);
    // 恢复文本选择，允许用户选择页面内容
    document.body.style.userSelect = '';
}

/**
 * 获取工具容器的尺寸信息
 * @returns {DOMRect} - 元素的尺寸信息，如果没有找到元素则返回 { width: 0 }
 */
function rect() {
    const el = document.querySelector('.search-text-container');
    return el ? el.getBoundingClientRect() : { width: 0 };
}
</script>

<style scoped lang="less">
.search-text-container {
    width: 300px;
    display: flex;
    background-color: #fff;
    border-radius: 8px;
    position: fixed;
    box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
    padding: 6px 10px 6px 16px;
    box-sizing: border-box;
    z-index: 999;

    .search-drag {
        font-size: 12px;
        position: absolute;
        top: 9px;
        left: 0;
        cursor: all-scroll;
    }

    .search-left {
        padding-right: 10px;
        border-right: 1px solid #dcdfe6;
    }

    .search-right {
        padding-left: 10px;
        flex: 1;
    }
}

.open-btn {
    transition: all 0.3s;
    cursor: pointer;

    &.open {
        transform: rotate(90deg);
    }
}

.search-wrap,
.replace-wrap {
    display: flex;
    align-items: center;
    gap: 10px;
}

.search-divider {
    display: inline-block;
    width: 100%;
    border-bottom: 1px solid #dcdfe6;
    margin: 5px 0;
}

.search-right .iconfont {
    cursor: pointer;
    color: #333;

    &:hover,
    &.active {
        color: var(--main-color);
    }
}
</style>